from django.shortcuts import render

# Create your views here.

import json
import os
import uuid
import hashlib
import openpyxl
from apps.student.tests import read_excel_dict


#导入Q查询，  or
from django.db.models import Q

from student.models import Student

from django.http import JsonResponse
#导入settings
from django.conf import settings

from django.contrib.auth import authenticate, login
from rest_framework.authtoken.models import Token
from rest_framework.permissions import AllowAny,IsAuthenticated
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from rest_framework.views import APIView
from rest_framework.authentication import TokenAuthentication




def is_exsits_sno(request):
    """判断学号是否存在"""
    #接收传递过来的不号
    data = json.loads(request.body.decode('utf-8'))
    #进行校验
    try:
        obj_students = Student.objects.filter(sno=data['sno'])
        if  obj_students.count() == 0:
            return JsonResponse({'code': 1, 'exists': False})
        else:
            return JsonResponse({'code': 1, 'exists': True })
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': '校验学号失败，具体原因：{}'.format(str(e))})


#----------------------------------------------------------------------------------

class LoginViewSet(APIView):
    permission_classes = (AllowAny,)      #todo 登录允许每个人访问,元祖要加逗号


    def post(self, request, *args, **kwargs):

        username = request.data.get('username')
        password = request.data.get('password')
        user = authenticate(username=username,
                            password=password)
        if not user:
            result = {"code": 1,
                      "msg": "用户名或密码错误"}
            return JsonResponse(result)
        else:
            # 先删除原有token
            oid_token = Token.objects.filter(user=user)
            oid_token.delete()
            # 创建新的token
            token = Token.objects.create(user=user)
            result = {"code": 0,
                      "msg": "login success!",
                      "username": user.username,
                      "token": token.key
                      }
            return JsonResponse(result)



class getAllStudent(APIView):
    '''rest_framework序列化'''
    authentication_classes = (TokenAuthentication,)   # token认证方式
    permission_classes = (IsAuthenticated,)      # 登录用户才能访问这个接口

    def get(self, request, format=None):
        try:
            # 使用ORM获取所有学生信息
            obj_students = Student.objects.all().values()
            # 把结果转为
            students = list(obj_students)
            return JsonResponse({'code': 1, 'data': students})
        except Exception as e:
            # 如果出现异常，返回
            return JsonResponse({'code': 0, 'msg': "获取学生信息出现异常，具体错误" + str(e)})


class queryStudents(APIView):
    '''rest_framework序列化'''
    authentication_classes = (TokenAuthentication,)  # token认证方式
    permission_classes = (IsAuthenticated,)  # 登录用户才能访问这个接口

    def post(self, request, format=None):
        """查询学生信息"""
        # 接收传递过来的查询条件， axios默认为json, --- 字典类型（'inputstr'） -- data['inputstr']
        data = json.loads(request.body.decode('utf-8'))
        try:
            # 使用ORM获取所有学生信息,并把对你转换成json格式
            obj_students = Student.objects.filter(
                Q(sno__icontains=data['inputstr']) | Q(name__icontains=data['inputstr']) |
                Q(gender__contains=data['inputstr']) | Q(mobile__icontains=data['inputstr']) |
                Q(email__icontains=data['inputstr']) | Q(address__icontains=data['inputstr'])).values()

            # 把结果转为
            students = list(obj_students)
            return JsonResponse({'code': 1, 'data': students})
        except Exception as e:
            # 如果出现异常，返回
            return JsonResponse({'code': 0, 'msg': "查询学生信息出现异常，具体错误" + str(e)})


class checkSno(APIView):
    '''rest_framework序列化'''
    authentication_classes = (TokenAuthentication,)  # token认证方式
    permission_classes = (IsAuthenticated,)  # 登录用户才能访问这个接口

    def post(self, request, format=None):
        """判断学号是否存在"""
        # 接收传递过来的不号
        data = json.loads(request.body.decode('utf-8'))
        # 进行校验
        try:
            obj_students = Student.objects.filter(sno=data['sno'])
            if obj_students.count() == 0:
                return JsonResponse({'code': 1, 'exists': False})
            else:
                return JsonResponse({'code': 1, 'exists': True})
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': '校验学号失败，具体原因：{}'.format(str(e))})



class addStudent(APIView):
    '''rest_framework序列化'''
    authentication_classes = (TokenAuthentication,)  # token认证方式
    permission_classes = (IsAuthenticated,)  # 登录用户才能访问这个接口

    def post(self, request, format=None):
        data = json.loads(request.body.decode('utf-8'))
        # 添加到数据库
        try:
            obj_student = Student(sno=data['sno'], name=data['name'], gender=data['gender'],
                                  birthday=data['birthday'], mobile=data['mobile'],
                                  email=data['email'], address=data['address'], image=data['image'])
            # 执行添加
            obj_student.save()
            # 使用ORM获取所有学生信息、获取所有的学生
            obj_students = Student.objects.all().values()
            # 把结果转为
            students = list(obj_students)
            return JsonResponse({'code': 1, 'data': students})
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': '数据库出现异常，具体原因' + str(e)})


class updataStudent(APIView):
    '''rest_framework序列化'''
    authentication_classes = (TokenAuthentication,)  # token认证方式
    permission_classes = (IsAuthenticated,)  # 登录用户才能访问这个接口

    def post(self, request, format=None):
        """添加学生到数据库"""
        # 接收前端传递过来的值
        data = json.loads(request.body.decode('utf-8'))
        try:
            # 查找到要修改的学生信息
            obj_student = Student.objects.get(sno=data['sno'])
            # 依次修改
            obj_student.name = data['name']
            obj_student.gender = data['gender']
            obj_student.birthday = data['birthday']
            obj_student.mobile = data['mobile']
            obj_student.email = data['email']
            obj_student.address = data['address']
            obj_student.image = data['image']
            # 执行添加
            obj_student.save()
            # 使用ORM获取所有学生信息、获取所有的学生
            obj_students = Student.objects.all().values()
            # 把结果转为
            students = list(obj_students)
            return JsonResponse({'code': 1, 'data': students})
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': '修改数据出现异常，具体原因' + str(e)})


class deleteStudent(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):
        data = json.loads(request.body.decode('utf-8'))
        try:
            obj_student = Student.objects.get(sno=data['sno'])
            obj_student.delete()
            # 使用ORM获取所有学生信息、获取所有的学生
            obj_students = Student.objects.all().values()
            # 把结果转为
            students = list(obj_students)
            return JsonResponse({'code': 1, 'data': students})
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': '删除数据出现异常，具体原因' + str(e)})


class deleteStudents(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    
    def post(self, request, format=None):
        data = json.loads(request.body.decode('utf-8'))
        print(data)
        try:
            for one_student in data['students']:
                # 查询当前记录
                obj_student = Student.objects.get(sno=one_student['sno'])
                # 执行删除
                obj_student.delete()
            # 使用ORM获取所有学生的信息，获取所有的学生
            obj_students = Student.objects.all().values()
            # 把结果转为
            students = list(obj_students)
            return JsonResponse({'code': 1, 'data': students})
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': '批量删除数据出现异常，具体原因' + str(e)})


class uploadStudentImg(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):
        """接收上传的文件"""
        # 接收上传的文件
        rev_file = request.FILES.get('avatar')
        # 判断是否有文件
        if not rev_file:
            return JsonResponse({'code': 0, 'msg': '图片不存在'})
        # 获得一个唯一的名称： uuid + hash
        new_name = get_random_str()
        # 准备写的URL
        file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1])
        # 写入到本地磁盘
        try:
            f = open(file_path, 'wb')
            # 多次写入
            for i in rev_file.chunks():
                f.write(i)
            # 要关闭
            f.close()
            return JsonResponse({'code': 1, 'name': new_name + os.path.splitext(rev_file.name)[1]})
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': str(e)})

class inputStudent(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):
        # 接收上传的文件
        rev_file = request.FILES.get('Excel')
        # 判断是否有文件
        if not rev_file:
            return JsonResponse({'code': 0, 'msg': '导入文件不存在'})
        # 获得一个唯一的名称： uuid + hash
        new_name = get_random_str()
        # 准备写的URL
        file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1])
        # 写入到本地磁盘
        try:
            f = open(file_path, 'wb')
            # 多次写入
            for i in rev_file.chunks():
                f.write(i)
            # 要关闭
            f.close()
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': str(e)})
        students = read_excel_dict(file_path)
        success = 0
        sno = []
        try:
            for data in students:
                try:
                    obj_student = Student.object.create(sno=data['sno'], name=data['name'], gender=data['gender'],
                                                        birthday=data['birthday'], mobile=data['mobile'],
                                                        email=data['email'], address=data['address'])
                    # #执行添加
                    # obj_student.save()
                    success += 1
                except Exception:
                    sno.append(data['sno'])
            # 使用ORM获取所有学生信息、获取所有的学生
            obj_students = Student.objects.all().values()
            # 把结果转为
            stus = list(obj_students)
            return JsonResponse(
                {'code': 1, 'msg': '导入成功' + str(success) + '条，失败' + str(len(students) - success) + '条', 'sno': sno,
                 'data': stus})
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': '数据库出现异常，具体原因' + str(e)})

class exportStudent(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):
        try:
            obj_students = Student.objects.all().values()
            file_name = data_write_execl(obj_students)
            return JsonResponse({'code': '1', 'file_name': file_name})
        except Exception as e:
            return JsonResponse({'code': 0, 'msg': '导出失败，具体原因' + str(e)})




#----------------------------------------------------------------------------------






def get_studensts(request):
    """
    获取学生数据
    :param request:
    :return:
    """
    try:
        #使用ORM获取所有学生信息
        obj_students = Student.objects.all().values()
        #把结果转为
        students = list(obj_students)
        return JsonResponse({'code': 1, 'data': students})
    except Exception as e:
        # 如果出现异常，返回
        return JsonResponse({'code': 0, 'msg': "获取学生信息出现异常，具体错误" + str(e)})

def query_students(request):
    """查询学生信息"""
    # 接收传递过来的查询条件， axios默认为json, --- 字典类型（'inputstr'） -- data['inputstr']
    data = json.loads(request.body.decode('utf-8'))
    try:
        #使用ORM获取所有学生信息,并把对你转换成json格式
        obj_students = Student.objects.filter(Q(sno__icontains=data['inputstr']) | Q(name__icontains=data['inputstr'])|
                                              Q(gender__contains=data['inputstr']) | Q(mobile__icontains=data['inputstr']) |
                                              Q(email__icontains=data['inputstr']) | Q(address__icontains=data['inputstr'])).values()

        #把结果转为
        students = list(obj_students)
        return JsonResponse({'code': 1, 'data': students})
    except Exception as e:
        # 如果出现异常，返回
        return JsonResponse({'code': 0, 'msg': "查询学生信息出现异常，具体错误" + str(e)})

def add_student(request):
    """添加学生到数据库"""
    #接收前端传递过来的值
    data = json.loads(request.body.decode('utf-8'))
    #添加到数据库
    try:
        obj_student = Student(sno=data['sno'], name=data['name'], gender=data['gender'],
                              birthday=data['birthday'], mobile=data['mobile'],
                              email=data['email'], address=data['address'], image=data['image'])
        #执行添加
        obj_student.save()
        # 使用ORM获取所有学生信息、获取所有的学生
        obj_students = Student.objects.all().values()
        # 把结果转为
        students = list(obj_students)
        return JsonResponse({'code': 1, 'data': students})
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': '数据库出现异常，具体原因' + str(e)})

def update_student(request):
    """添加学生到数据库"""
    # 接收前端传递过来的值
    data = json.loads(request.body.decode('utf-8'))
    try:
        #查找到要修改的学生信息
        obj_student = Student.objects.get(sno=data['sno'])
        #依次修改
        obj_student.name = data['name']
        obj_student.gender = data['gender']
        obj_student.birthday = data['birthday']
        obj_student.mobile = data['mobile']
        obj_student.email = data['email']
        obj_student.address = data['address']
        obj_student.image = data['image']
        # 执行添加
        obj_student.save()
        # 使用ORM获取所有学生信息、获取所有的学生
        obj_students = Student.objects.all().values()
        # 把结果转为
        students = list(obj_students)
        return JsonResponse({'code': 1, 'data': students})
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': '修改数据出现异常，具体原因' + str(e)})

def delete_student(request):
    data = json.loads(request.body.decode('utf-8'))
    try:
        obj_student = Student.objects.get(sno=data['sno'])
        obj_student.delete()
        # 使用ORM获取所有学生信息、获取所有的学生
        obj_students = Student.objects.all().values()
        # 把结果转为
        students = list(obj_students)
        return JsonResponse({'code': 1, 'data': students})
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': '删除数据出现异常，具体原因' + str(e)})

def delete_students(request):
    data = json.loads(request.body.decode('utf-8'))
    print(data)
    try:
        for one_student in data['students']:
            # 查询当前记录
            obj_student = Student.objects.get(sno=one_student['sno'])
            # 执行删除
            obj_student.delete()
        #使用ORM获取所有学生的信息，获取所有的学生
        obj_students = Student.objects.all().values()
        # 把结果转为
        students = list(obj_students)
        return JsonResponse({'code': 1, 'data': students})
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': '批量删除数据出现异常，具体原因' + str(e)})

def upload(request):
    """接收上传的文件"""
    #接收上传的文件
    rev_file = request.FILES.get('avatar')
    #判断是否有文件
    if not rev_file:
        return JsonResponse({'code': 0, 'msg': '图片不存在'})
    #获得一个唯一的名称： uuid + hash
    new_name = get_random_str()
    #准备写的URL
    file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1])
    #写入到本地磁盘
    try:
        f = open(file_path, 'wb')
        #多次写入
        for i in rev_file.chunks():
            f.write(i)
        #要关闭
        f.close()
        return JsonResponse({'code': 1, 'name': new_name + os.path.splitext(rev_file.name)[1]})
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': str(e)})


def get_random_str():
    #获取uuid的随机数
    uuid_val = uuid.uuid4()
    #获取uuid的随机数字符串
    uuid_str = str(uuid_val).encode('utf-8')
    #获取md5实例
    md5 = hashlib.md5()
    #拿取uuid的md5摘要
    md5.update(uuid_str)
    #返回固定长度的字符串
    return md5.hexdigest()


def inputSutdet(request):
    # 接收上传的文件
    rev_file = request.FILES.get('Excel')
    # 判断是否有文件
    if not rev_file:
        return JsonResponse({'code': 0, 'msg': '导入文件不存在'})
    # 获得一个唯一的名称： uuid + hash
    new_name = get_random_str()
    # 准备写的URL
    file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1])
    # 写入到本地磁盘
    try:
        f = open(file_path, 'wb')
        # 多次写入
        for i in rev_file.chunks():
            f.write(i)
        # 要关闭
        f.close()
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': str(e)})
    students = read_excel_dict(file_path)
    success = 0
    sno = []
    try:
        for data in students:
            try:
                obj_student = Student.object.create(sno=data['sno'], name=data['name'], gender=data['gender'],
                                      birthday=data['birthday'], mobile=data['mobile'],
                                      email=data['email'], address=data['address'])
                # #执行添加
                # obj_student.save()
                success += 1
            except Exception:
                sno.append(data['sno'])
        # 使用ORM获取所有学生信息、获取所有的学生
        obj_students = Student.objects.all().values()
        # 把结果转为
        stus = list(obj_students)
        return JsonResponse({'code': 1, 'msg': '导入成功' + str(success) + '条，失败' + str(len(students) - success) + '条', 'sno': sno, 'data': stus})
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': '数据库出现异常，具体原因' + str(e)})



def exportExcel(request):
    try:
        obj_students = Student.objects.all().values()
        file_name = data_write_execl(obj_students)
        return JsonResponse({'code': '1', 'file_name': file_name})
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': '导出失败，具体原因' + str(e)})




def data_write_execl(studensts):
    workbook = openpyxl.Workbook()
    index = 0
    for data in studensts:
        index += 1
        workbook['A' + str(index)] = data['sno']
        workbook['B' + str(index)] = data['name']
        workbook['C' + str(index)] = data['gender']
        workbook['D' + str(index)] = data['birthday']
        workbook['E' + str(index)] = data['mobile']
        workbook['F' + str(index)] = data['email']
        workbook['G' + str(index)] = data['address']
        workbook['H' + str(index)] = data['img']
    # 获得一个唯一的名称： uuid + hash
    new_name = get_random_str()
    # 准备写的URL
    file_path = os.path.join(settings.MEDIA_ROOT, new_name + '.xlsx')
    workbook.save(file_path)
    return new_name + '.xlsx'

